package cn.bnjy.util;

import com.alibaba.fastjson.JSON;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.sun.image.codec.jpeg.JPEGCodec;
import com.sun.image.codec.jpeg.JPEGImageDecoder;
import com.sun.image.codec.jpeg.JPEGImageEncoder;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
import java.util.List;
import java.util.Map;

/**
 * 描述：图片工具类
 *
 * @since: 2018/12/9 14:53
 * @author: chavin
 */
@Slf4j
public class ImgUtils {

    private ImgUtils() {

    }

    /**
     * 合成图片
     * @param sourceImg 主图片
     * @param targetImgMapList 目标图片及x和y位置
     * @param targetTextMapList 目标文字及x和y位置
     * @return
     */
    public static String compound(String sourceImg, List<Map<String, String>> targetImgMapList, List<Map<String, String>> targetTextMapList) {
        // 参数校验
        if(StringUtils.isBlank(sourceImg) || (CollectionUtils.isBlankList(targetImgMapList) && CollectionUtils.isBlankList(targetTextMapList))) {
            return sourceImg;
        }
        log.info("合成图片，sourceImg: {}, 图片参数：{}，文字参数：{}", sourceImg, JSON.toJSONString(targetImgMapList), JSON.toJSONString(targetTextMapList));
        LocalDateTime startTime = LocalDateTime.now();
        String compoundImg = String.valueOf(System.currentTimeMillis()) + ".jpg";
        InputStream sourceInputStream = null;
        OutputStream outputStream = null;
        try {
            // 校验主图片
            File sourceFile = new File(sourceImg);
            if(!sourceFile.exists()) {
                return sourceImg;
            }
            String filePath = CommonUtils.isWindows() ? "D://wx/static/images/qrcode" : "/home/wx/static/images/qrcode";
            File pfile = new File(filePath);
            if(!pfile.exists()) {
                pfile.mkdirs();
            }
            compoundImg = filePath + File.separator + compoundImg;
            // 主图片
            sourceInputStream = new FileInputStream(sourceImg);
            // 通过JPEG图象流创建JPEG数据流解码器
            JPEGImageDecoder jpegDecoder = JPEGCodec.createJPEGDecoder(sourceInputStream);
            // 解码当前JPEG数据流，返回BufferedImage对象
            BufferedImage buffImg = jpegDecoder.decodeAsBufferedImage();
            // 得到画笔对象
            Graphics graphics = buffImg.getGraphics();
            // 合成图片
            if(CollectionUtils.isNotBlankList(targetImgMapList)) {
                for(int i = 0 ; i < targetImgMapList.size(); i ++) {
                    Map<String, String> targetMap = targetImgMapList.get(i);
                    String targetImg = targetMap.get("img");
                    if(StringUtils.isBlank(targetImg)) {
                        return sourceImg;
                    }
                    int x = Integer.parseInt(targetMap.get("x"));
                    int y = Integer.parseInt(targetMap.get("y"));

                    // 小图片的路径
                    ImageIcon imgIcon = new ImageIcon(targetImg);
                    // 得到Image对象
                    Image img = imgIcon.getImage();
                    // 将小图片绘到大图片上,(x,y)表示你的小图片在大图片上的位置
                    if(targetMap.containsKey("width") && targetMap.containsKey("height")) {
                        int width = Integer.parseInt(targetMap.get("width"));
                        int height = Integer.parseInt(targetMap.get("height"));
                        graphics.drawImage(img, x, y, width, height, null);
                    } else {
                        graphics.drawImage(img, x, y, null);
                    }
                }
            }
            // 合成文字
            if(CollectionUtils.isNotBlankList(targetTextMapList)) {
                for(int i = 0 ; i < targetTextMapList.size(); i ++) {
                    Map<String, String> targetMap = targetTextMapList.get(i);
                    String targetText = targetMap.get("text");
                    if(StringUtils.isBlank(targetText)) {
                        return sourceImg;
                    }
                    int x = Integer.parseInt(targetMap.get("x"));
                    int y = Integer.parseInt(targetMap.get("y"));
                    Font font = new Font("微软雅黑", Font.BOLD, 16);
                    Color txtColor = new Color(241, 108, 77);
                    graphics.setColor(txtColor);
                    graphics.setFont(font);
                    graphics.drawString(targetText, x, y); //表示这段文字在图片上的位置(cx,cy) .第一个是你设置的内容。
                }
            }
            graphics.dispose();
            outputStream = new FileOutputStream(compoundImg);
            //创键编码器，用于编码内存中的图象数据
            JPEGImageEncoder en = JPEGCodec.createJPEGEncoder(outputStream);
            en.encode(buffImg);
        } catch (Exception e) {
            log.error("合成图片失败:", e);
            return sourceImg;
        } finally {
            try {
                if(sourceInputStream != null) {
                    sourceInputStream.close();
                }
            } catch (IOException e) {
                log.error("关闭输入流异常:", e);
            }
            try {
                if(outputStream != null) {
                    outputStream.close();
                }
            } catch (IOException e) {
                log.error("关闭输出流异常:", e);
            }
        }
        LocalDateTime endTime = LocalDateTime.now();
        long time = ChronoUnit.MILLIS.between(startTime, endTime);
        log.info("合成完毕，耗时：{}ms，返回结果：{}", time, compoundImg);
        return compoundImg;
    }

    public static void main(String[] args) {
        List<Map<String, String>> targetImgMapList = Lists.newArrayList();
        Map<String, String> targetImgMap = Maps.newHashMap();
        targetImgMap.put("img", "D:\\wx\\static\\images\\qrcode\\1544340284250.jpg");
        targetImgMap.put("x", "169");
        targetImgMap.put("y", "415");
        targetImgMap.put("width", "143");
        targetImgMap.put("height", "143");
        targetImgMapList.add(targetImgMap);
        /*List<Map<String, String>> targetTextMapList = Lists.newArrayList();
        // 126 385
        Map<String, String> targetTextMap = Maps.newHashMap();
        targetTextMap.put("text", "abcdefghi");
        targetTextMap.put("x", "120");
        targetTextMap.put("y", "400");
        targetTextMapList.add(targetTextMap);*/
        String sourceImg = "D:\\wx\\static\\images\\qrcode\\qrcode-template.jpg";
        System.out.println(compound(sourceImg, targetImgMapList, null));
    }

}
